#include <iostream>
#include <string.h>
#include <exception>

using namespace std;

struct stduent
{
    stduent()
    {
    }
    stduent(const char *pName, int age)
    {
        strcpy(name, pName);
        this->age = age;
    }
    char name[128];
    int age;
};

class test
{
public:
    void operator()(stduent s1)
    {
        cout << s1.name << " " << s1.age << endl;
    }
};

class testInt
{
public:
    void operator()(int s1)
    {
        cout << s1 << endl;
    }
};

template <class T, class printType>
class myList
{
private:
    struct Node
    {
        Node(T data) // 定义data对象，T是student类，定义时调用了构造函数，所以student类中必须要有默认构造函数
        {
            this->data = data;
            pNext = NULL;
        }
        T data;
        Node *pNext;
    };

    Node *pHead; // 头指针
    Node *pRear; // 尾指针
public:
    class Iterator
    {
    public:
        Node *pNode;
        T operator*()
        {
            return pNode->data;
        }

        void operator++(int) // 括号中的Int是告诉系统++是放在变量后面使用的
        {
            pNode = pNode->pNext;
        }
    };

    myList()
    {
        pHead = pRear = NULL;
    }

    void push_back(T data)
    {
        Node *pNew = new Node(data);
        if (pHead == NULL) // 如果链表是空的，头尾都指向新的节点
        {
            pHead = pNew;
            pRear = pNew;
        }
        else
        {
            pRear->pNext = pNew;
            pRear = pNew;
        }
    }

    void print(printType t)
    {
        Node *p = pHead;
        while (p)
        {
            t(p->data); // 仿函数
            p = p->pNext;
        }
    }

    Iterator begin()
    {
        Iterator it;
        it.pNode = pHead; // 迭代器里面的指针指向第一个节点（头节点）
        return it;
    }
};

int main()
{
    myList<stduent, test> l1;
    l1.push_back(stduent("zhangsan", 100));
    l1.push_back(stduent("lisi", 98));
    l1.push_back(stduent("wangwu", 00));
    l1.print(test());

    myList<int, testInt> l2;
    l2.push_back(10);
    l2.push_back(20);
    l2.push_back(30);
    l2.print(testInt());

    myList<int, testInt>::Iterator it = l2.begin();
    it++;
    cout << *it << endl;

    return 0;
}
